var createError = require("http-errors");
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");

var session = require("express-session");
const MongoStore = require("connect-mongo");

var indexRouter = require("./routes/index");
var usersRouter = require("./routes/users");
var loginRouter = require("./routes/login");

var app = express();

// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");

app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));

// 应用中间件需要在路由中间件之前执行
app.use(
  session({
    name: "xiaomingCookie", // cookie 名字
    secret: "fasgsrsxsrsa13634", // 秘钥
    cookie: {
      maxAge: 1000 * 60 * 60, // 一小时 单位 ms
      // 浏览器cookie内的时间是 德国格林尼治时间  国内是需要加八个小时（东八区
      secure: false, // 表示cookie是在http还是https内使用  不能串
    },
    // 重新设置 session 后  会自动重新计算过期时间(平常普通掉接口或者页面是不会刷新cookie过期时间的)
    // 为了达到这种实时刷新过期时间的效果  需要在 应用中间件 每次请求都重新设置 session
    resave: true,
    saveUninitialized: true, // 初次链接是否生成 cookie
    store: MongoStore.create({
      // 同一账户不同浏览器登录也会生成不同的session到数据库内
      mongoUrl: "mongodb://127.0.0.1:27017/xiaoming_session",
      ttl: 1000 * 60 * 10, // 过期时间    需要和cookie的过期时间统一
    }),
  })
);

// 全局的 页面 和 接口 中间件
app.use((req, res, next) => {
  // console.log(req.url, req.session);
  /**
   * 本项目中 登录界面 和 登录接口都包含 login 所以只需要判断存在login则
   *  */
  if (req.url.includes("login")) {
    next();
    // 前端手动跳转到 /login  无法拦截到 /  因为无任何请求 后端无法感知
    // if(req.url === '/login' && req.session.peson) {
    //   redirect('/')
    // }
    return;
  }

  // // 浏览器的cookie一直存在  但无效  登录之后赋值了才有效
  if (req.session.person) {
    req.session.data = Date.now(); // 重新设置一个属性表示 session 实时更新
    next();
  } else {
    // 是接口吗  不是的话  重定向到登陆界面  是的话返回code码让前端自己跳
    if (req.url.includes("api")) {
      res
        .status(401)
        .send(JSON.stringify({ status: "error", statusCode: "401" }));
    } else {
      res.redirect("/login");
    }
  }
});

app.use("/", indexRouter);
app.use("/api", usersRouter);
app.use("/login", loginRouter);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get("env") === "development" ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render("error");
});

module.exports = app;
